package io.jft.doll.ui.roomList

import android.arch.lifecycle.ViewModelProviders
import android.os.Bundle
import com.alibaba.android.arouter.facade.annotation.Autowired
import com.alibaba.android.arouter.facade.annotation.Route
import com.alibaba.android.arouter.launcher.ARouter
import com.alibaba.android.vlayout.LayoutHelper
import com.alibaba.android.vlayout.layout.GridLayoutHelper
import com.g.base.api.ErrorCode
import com.g.base.extend.dp
import com.g.base.extend.observeEx
import com.g.base.extend.resultNotNull
import com.g.base.extend.toast
import com.g.base.room.entity.UserEntity
import com.g.base.room.repository.ListStatus
import com.g.base.room.repository.Status
import com.g.base.ui.BaseActivity
import com.g.base.ui.recyclerView.item.BaseItem
import com.g.base.ui.recyclerView.setupRecyclerView
import io.jft.doll.R
import io.jft.doll.databinding.ViewSwipeRecyclerBinding
import io.jft.doll.model.viewModel.RoomListViewModel
import io.jft.doll.room.entity.common.RoomCEntity
import io.jft.doll.router.RouterPage
import io.jft.doll.tcp.TcpHelp
import io.jft.doll.ui.roomList.bind.RoomItemBind
import kotlin.math.max

@Route(path = RouterPage.RoomListActivity)
class RoomListActivity : BaseActivity<ViewSwipeRecyclerBinding>() {
    override var hasToolbar: Boolean = true

    @JvmField
    @Autowired
    var title: String? = null

    @JvmField
    @Autowired
    var groupId: String = ""

    private val adapter by lazy { setupRecyclerView(contentView.recyclerView) }
    private val roomViewModel by lazy { ViewModelProviders.of(this).get(RoomListViewModel::class.java) }
    private var status: ListStatus = ListStatus.Content
    private var data: List<RoomCEntity>? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ARouter.getInstance().inject(this)
        setContentView(R.layout.view_swipe_recycler)
        initView()
        obsData()
    }

    override fun onReload() {
        roomViewModel.operateRoomList(0, groupId)
    }

    override fun onTokenChange(data: UserEntity?) {
        if (data == null) {
            showNeedOauth()
        } else {
            onReload()
        }
    }

    private fun initView() {
        //title
        toolbar.title = title
        toolbar.setNavigationIcon(R.drawable.ic_arrow_back_toolbar_24dp)
        toolbar.setNavigationOnClickListener { finishAfterTransition() }
        //更多
        adapter.setOnLoadingListener {
            if (status != ListStatus.Content) {
                toast("请等待其他 加载操作完成")
                adapter.setLoadingFailed()
            } else {
                roomViewModel.operateRoomList(data?.size ?: 0, groupId)
                status = ListStatus.LoadMore
            }
        }
        //刷新
        contentView.swipeLayout.setOnRefreshListener {
            if (status != ListStatus.Content) {
                toast("请等待其他 加载操作完成")
                contentView.swipeLayout.isRefreshing = false
            } else {
                roomViewModel.operateRoomList(0, groupId, data?.size ?: 20)
                status = ListStatus.Refreshing
            }
        }

        val dp8 = 8.dp()
        adapter.layoutHelpers = arrayListOf(GridLayoutHelper(2, 0, dp8, dp8).apply {
            setMargin(dp8, dp8, dp8, dp8)
            setAutoExpand(false)
        } as LayoutHelper)

    }

    private fun obsData() {
        onReload()

        roomViewModel.obsRoomList()
                .resultNotNull()
                .observeEx(this) {
                    when (it.status) {
                        Status.Loading -> {
                            if (status == ListStatus.Content) showLoading()
                        }
                        Status.Content -> {
                            data = it.data!!
                            if (data!!.size < max(roomViewModel.lastRequestSize, roomViewModel.limit))
                                adapter.setLoadingNoMore()
                            else
                                adapter.setLoadingSucceed()

                            contentView.swipeLayout.isRefreshing = false
                            applyData()
                            showContentView()
                            status = ListStatus.Content
                        }
                        Status.Error -> {
                            when (status) {
                                ListStatus.Content -> if (it.error?.code == ErrorCode.EMPTY) showEmpty(it.error?.message) else showError(it.error?.message)
                                ListStatus.LoadMore -> if (it.error?.code == ErrorCode.EMPTY) adapter.setLoadingNoMore() else adapter.setLoadingFailed()
                                ListStatus.Refreshing -> contentView.swipeLayout.isRefreshing = false
                            }
                            status = ListStatus.Content
                        }
                    }
                }
    }

    private fun applyData() {
        val data = this.data ?: return
        adapter.diffItems.addAll(data.map(this::createRoomItemBind))
        adapter.layoutManager.layoutHelpers.first().apply {
            itemCount = data.size
            setRange(0, data.size - 1)
        }
        adapter.calcDiffAndDispatchUpdate(
                { baseItem: BaseItem<*>, _: Int, baseItem1: BaseItem<*>, _: Int ->
                    (baseItem as RoomItemBind).item.id == (baseItem1 as RoomItemBind).item.id
                },
                { baseItem: BaseItem<*>, _: Int, baseItem1: BaseItem<*>, _: Int ->
                    (baseItem as RoomItemBind).item == (baseItem1 as RoomItemBind).item
                })
    }

    private fun createRoomItemBind(item: RoomCEntity): RoomItemBind {
        val roomItemBind = RoomItemBind(item)
        roomItemBind.setOnClickListener {
            if (it.id == R.id.button) {
                TcpHelp.appointmentRoom(item.id, !roomItemBind.item.isAppointment)
            } else {
                ARouter.getInstance().build(RouterPage.RoomActivity).withString("roomId", item.id).navigation(this)
            }
        }
        return roomItemBind
    }
}